package com.zx1316.javasimpledoudizhu.client;

import com.zx1316.javasimpledoudizhu.misc.Card;

import java.util.Vector;

public class Judge {
    private DiscardType type = DiscardType.ANY;
    private int maxCard = 15;
    private int length;
    private int[] count; // 每种牌的数量
    private int[] groupCount;// 单、双、三、四牌的数量

    public void judgeOther(Vector<Card> discards) {
        processCard(discards);
        int i, j;
        for (i = 0; i < 15 && count[i] == 0; i++) ;
        if (groupCount[1] == 0 && groupCount[2] == 0 && groupCount[3] == 0) {
            length = groupCount[0];
            type = DiscardType.SINGLE;
            maxCard = i;
        } else if (groupCount[0] == 0 && groupCount[2] == 0 && groupCount[3] == 0) {
            length = groupCount[1];
            type = DiscardType.DOUBLE;
            maxCard = i;
        } else if (groupCount[3] == 1 && groupCount[2] == 0) {
            for (j = i; count[j] != 4; j++) ;
            maxCard = j;
            if (groupCount[0] == 0 && groupCount[1] == 0) {
                type = DiscardType.BOMB;
            } else if (groupCount[0] + 2 * groupCount[1] == 2) {
                type = DiscardType.QUAD_SINGLE;
            } else if (groupCount[0] == 0 && groupCount[1] == 2) {
                type = DiscardType.QUAD_DOUBLE;
            }
        } else if (count[0] == 1 && count[1] == 1) {
            type = DiscardType.JOKER_BOMB;
        } else if (groupCount[2] != 0 && groupCount[3] == 0) {
            for (j = i; count[j] != 3; j++) ;
            maxCard = j;
            length = groupCount[2];
            if (groupCount[0] + 2 * groupCount[1] == groupCount[2]) {
                type = DiscardType.TRIPLE_SINGLE;
            } else if (groupCount[1] == groupCount[2] && groupCount[0] == 0) {
                type = DiscardType.TRIPLE_DOUBLE;
            } else if (groupCount[0] == 0 && groupCount[1] == 0) {
                type = DiscardType.TRIPLE;
            }
        }
    }

    public boolean judgeSelf(Vector<Card> discards) {
        processCard(discards);
        int i, j;
        for (i = 0; i < 15 && count[i] == 0; i++) ;
        if (count[0] == 1 && count[1] == 1) {
            return groupCount[1] == 0 && groupCount[2] == 0 && groupCount[3] == 0;
        } else {
            if (groupCount[1] == 0 && groupCount[2] == 0 && groupCount[3] == 0) {
                for (j = i; j < 15 && count[j] != 0; j++) ;
                return i < maxCard && (j - i == 1 || j - i >= 5 && i >= 3) && j - i == groupCount[0] && (groupCount[0] == length || type == DiscardType.ANY) && (type == DiscardType.ANY || type == DiscardType.SINGLE);
            } else if (groupCount[0] == 0 && groupCount[2] == 0 && groupCount[3] == 0) {
                for (j = i; j < 15 && count[j] != 0; j++) ;
                return i < maxCard && (j - i == 1 || j - i >= 3 && i >= 3) && j - i == groupCount[1] && (groupCount[1] == length || type == DiscardType.ANY) && (type == DiscardType.ANY || type == DiscardType.DOUBLE);
            } else if (groupCount[3] == 1 && groupCount[2] == 0) {
                for (j = i; count[j] != 4; j++) ;
                if (groupCount[0] == 0 && groupCount[1] == 0 && type != DiscardType.JOKER_BOMB) {
                    if (type == DiscardType.BOMB) {
                        return j < maxCard;
                    }
                    return true;
                }
                return j < maxCard && (groupCount[0] + 2 * groupCount[1] == 2 && (type == DiscardType.QUAD_SINGLE || type == DiscardType.ANY) || groupCount[0] == 0 && groupCount[1] == 2 && (type == DiscardType.QUAD_DOUBLE || type == DiscardType.ANY));
            } else if (groupCount[2] != 0 && groupCount[3] == 0) {
                int k;
                for (j = i; count[j] != 3; j++) ;
                for (k = j; k < 15 && count[k] == 3; k++) ;
                return j < maxCard && k - j == groupCount[2] && (groupCount[2] == length || type == DiscardType.ANY) && ((type == DiscardType.TRIPLE || type == DiscardType.ANY) && groupCount[0] == 0 && groupCount[1] == 0 || (type == DiscardType.TRIPLE_SINGLE || type == DiscardType.ANY) && 2 * groupCount[1] + groupCount[0] == groupCount[2] || (type == DiscardType.TRIPLE_DOUBLE || type == DiscardType.ANY) && groupCount[1] == groupCount[2] && groupCount[0] == 0);
            } else {
                return false;
            }
        }
    }

    public void clear() {
        type = DiscardType.ANY;
        maxCard = 15;
    }

    private void processCard(Vector<Card> discards) {
        count = new int[15];
        groupCount = new int[4];
        for (Card card : discards) {
            count[card.getRelative()]++;
        }
        for (int i = 0; i < 15; i++) {
            if (count[i] > 0) {
                groupCount[count[i] - 1]++;
            }
        }
    }
}
